package com.cmy.framework_base.crash

import android.content.Context
import android.os.Build
import java.io.PrintWriter
import java.io.StringWriter
import java.text.DateFormat
import java.text.SimpleDateFormat
import java.util.*

/**
 * @name:
 *  CrashHandler
 * @package:
 *  com.cmy.framework_base.crash
 * @date:
 *  2023/3/913:50
 * @author
 *    cmy
 * @description
 *
 */
class CrashHandler : Thread.UncaughtExceptionHandler {
    private val TAG = "CrashHandlerUtil"

    //程序Context对象
    private var mContext: Context? = null


    //系統默认UncaughtException处理类
    private val mDefaultHandler: Thread.UncaughtExceptionHandler by lazy {  Thread.getDefaultUncaughtExceptionHandler() }

    //用于格式化日期，作为日志名的一部分
    private val dateFormat: DateFormat = SimpleDateFormat("yyyy-MM-dd-HH-mm-ss", Locale.CHINA)


    //用来存储设备信息和异常信息
    private val infos = mutableMapOf<String,String>()


    // 外置存储卡默认预警临界值
    private val THRESHOLD_WARNING_SPACE: Long = 100 * 1024*1024



    companion object{
        // 保存文件时所需的最小空间的默认值
        val THRESHOLD_MIN_SPCAE: Long = 60 * 1024*1024
        //创建CrashHandlerUtil实列
         val instance: CrashHandler by lazy { CrashHandler() }
    }


    /**
     * 初始化
     */
    fun init(context: Context) {
        mContext = context
        //设置CrashHandler为程序默认处理器
        Thread.setDefaultUncaughtExceptionHandler(this)
    }


    override fun uncaughtException(thread: Thread, throwable: Throwable) {
        val sb = StringBuilder()

        mContext?.let {

            //1.获取当前应用程序的版本号.
          val packageManager =  it.packageManager
          val packageInfo = packageManager.getPackageInfo(it.packageName,0)
          sb.append("程序的版本号为:${packageInfo.versionName}").append("\n")
            //2.获取手机的硬件信息.
          val declaredFields = Build::class.java.declaredFields
            for (field in declaredFields){
               val name = field.name
               val value = field.get(null)?.toString()
                sb.append("$name = $value").append("\n")
            }
            //3.获取程序错误的堆栈信息 .
           val writer = StringWriter()
           val printWriter = PrintWriter(writer)
           throwable.printStackTrace(printWriter)
           val result = writer.toString()
           sb.append("错误堆栈信息:$result").append("\n")
        }
    }


    /**
     * 自定义错误处理，收集错误信息，发送错误报告等操作均在此完成
     * @return true：如果处理了该异常信息；否则返回 false
     */
    private fun handleException(ex:Throwable?):Boolean{
        if (ex == null){
            return false
        }

        mContext?.let { collectDeviceInfo(it) }

        return true
    }


    /**
     * 收集设备参数信息
     */
    private fun collectDeviceInfo(context: Context){
        context.let {
            //1.获取当前应用程序的版本号.
            val packageManager =  it.packageManager
            val packageInfo = packageManager.getPackageInfo(it.packageName,0)
            val versionName = if (packageInfo.versionName == null) "null" else packageInfo.versionName
            val versionCode = packageInfo.versionCode.toString() + ""
            infos["versionName"] = versionName
            infos["versionCode"] = versionCode

            //2.获取手机的硬件信息.
            val declaredFields = Build::class.java.declaredFields
            for (field in declaredFields){
                val name = field.name
                val value = field.get(null)?.toString()
                infos[name] = value?:"未知方法"
            }

        }
    }

}